﻿//@author A0083782W
//
// OutputDisplay handles the output to be displayed on the GUI
// e.g. Console Tab, Past Operations TextBox, Today Tab... etc
//
// The relevant follow up functions that display output after executing 
// user's commands such as add, edit, delete, etc are also in OutputDisplay
// in accordance with encapsulation separation of concerns.
//   
// OutputDisplay links up with Stdtosys class to convert its std::string to
// System::STring^

#pragma once
#include <iostream>  
#include <string>
#include "CommonDataType.h"
#include "EventStorage.h"
#include "OperationType.h"
#include "ThrowErrorCode.h"
#include "TECommonFunctions.h"
#include "ActionList.h"


using std::string;
using std::wstring;
using namespace StringManipulator;

//Start of constant list->
static con_str SPACE_STRING = " ";
static con_str SPACE_COMMA_SPACE = ", ";
static con_str SUPER_SPACE_STRING = "  ";
static con_str NEW_LINE = "\r\n";
static con_str STRING_YES = "YES";
static con_str STRING_NO = "NO";
static con_str STRING_START_WITH_COLON = "Start: ";
static con_str STRING_END_WITH_COLON = "End  : ";
static con_str STRING_TIME_WITH_COLON = "Time: ";
static con_str STRING_REMIND_WITH_COLON = "Remind: ";
static con_str STRING_NO_REMIND = "NO remind time";
static con_str STRING_SAVE_SUCCESS = "The data file is saved successfully";
static con_str STRING_DONE_ = "Done";
static con_str STRING_NOT_DONE = "Not done";
static con_str STRING_NOT_MISSED = "Not Missed";
static con_str STRING_MISSED_ = "Missed";
static con_str STRING_REMINDED_ = "Reminded";
static con_str STRING_NOT_REMINDED = "Not reminded";
static con_str STRING_DOT_SPACE = ". ";
static con_str STRING_DOT = ".";
static con_str STRING_QUOTATION = "'";
static con_str STRING_ADDED = "added successfully";
static con_str STRING_MODIFIED = "event at following indix modified successfully: ";
static con_str STRING_DELETED = "events at following indices deleted: ";
static con_str STRING_NOT_DELETED = "following indices are illegal and not deleted: ";
static con_str STRING_EMPTY_NO_DELETE = "Invalid input of event's index. Please delete again.";
static con_str STRING_TAGS = "Tags: ";
static con_str STRING_NO_TIME = "NO TIME FOUND";
static con_str STRING_NO_DATE = "NO DATE FOUND";
static con_str STRING_MODIFY_PROMPT = "Modify which of the above record(s)?";
static con_str STRING_MODIFY_OPTION = "1.Description  2.Time details  3.Repeat rules  4.Remind time  5.tags 0.Terminate Modify";
static con_str STRING_PLEASE_ENTER = "Please enter the new ";
static con_str STRING_YOU_HAVE_SELECTED = "You have selected ";
static con_str STRING_FOR_EDITING = "for editing";
static con_str STRING_DETAIL = "content";
static con_str STRING_TIME = "time";
static con_str STRING_REMIND_TIME = "Remind: ";
static con_str STRING_REPEAT = "Repeat: ";
static con_str STRING_NEVER_REPEAT = "NEVER repeat";
static con_str STRING_TAGS_SMALL = "tags";
static con_str STRING_COLON_SPACE = ": ";
static con_str STRING_MODIFY_SUCCESS = "successfully changed";
static con_str STRING_MODIFY_FAIL = "not modified (perhaps the index is not shown, wanna try another search before edit?)";
static con_str STRING_MODIFY_STEP2_ERROR = "Modifytype not correct. Should be from 1 to 5. Enter again.";
static con_str STRING_MODIFY_END = "Modify terminated";
static con_str STRING_MODIFY_EMPTY = "Illegal modify. Please input 'Modify index/indices'";
static con_str STRING_WELCOME = "Welcome! Dear User!";
static con_str STRING_HELP = "";
static con_str STRING_NOTHING = "Nothing ";
static con_str STRING_UNDONE = "steps undo successful";
static con_str STRING_ADD = "added";
static con_str STRING_DELETE = "deleted";
static con_str STRING_MODIFY = "edited";
static con_str STRING_MARKED = "events at following indices marked successfully: ";
static con_str STRING_NOT_MARKED = "following indices are illegal and not marked: ";
static con_str STRING_EMPTY_NO_MARK = "Invalid input of event's index. Please mark again";
static con_str STRING_ERROR_ADD_TOO_MANY_PARAMETERS = "Too many parameters for the add keyword.";
static con_str STRING_ERROR_ADD_NO_TASK_DESCIPTION = "A description of the task is never added.";
static con_str STRING_ERROR_DELETE_ILLEGAL_PARAMETER = "An illegal string for delete is entered, like 'delete 1 to a'.";
static con_str STRING_ERROR_MODIFY_ILLEGAL_PARAMETER = "Illegal string for modify indices are entered.";
static con_str STRING_ERROR_SEARCH_ILLEGAL_FLAGS = "Illegal flags are entered when searching.";
static con_str STRING_ERROR_UNDO_ILLEAGAL_NUMBER = "An unknow string was passed as a parameter to undo command.";
static con_str STRING_ERROR_UNKNOW_CHARACTERS = "Walah, why you anyhow input some random rubbish that\r\n"
												"we don't understand???? Please type \"help\" for the\r\n"
												"the list of commands that is available OOKKK???????";
static con_str STRING_ERROR_MARK_NO_FILETER = "Please input at least one parameter for filter.";
static con_str STRING_ERROR_MARK_NO_INDEX = "Please input a index for Mark function";
static con_str STRING_ERROR = "Error: ";
static con_str STRING_ERROR_UNKNOWN = "unknown error occured.";
static con_str STRING_SHOW_CONFIG_A = "Which display format to change?";  //ooooo
static con_str STRING_SHOW_CONFIG_B = "1.date, 2.time, 3. display order, other input to leave config";  //ooooo
static con_str STRING_ORDER_CONFIGED = "Display order changed successfully!";//ooooo
static con_str STRING_TIME_CONFIGED = "Time display format changed successfully!";//ooooo
static con_str STRING_ILLEGAL_CONFIG = "Illegal index! Enter again!";//ooooo
static con_str STRING_DATE_CONFIGED = "Date display format changed successfully!";//ooooo
static con_str STRING_EXIT_CONFIG = "Config exited";//ooooo
static con_str STRING_DATE_CONFIG_A = "Enter the index of preferred date format:";//ooooo
static con_str STRING_DATE_CONFIG_B = "0.DDMMYYYY, 1.DDMMYY, 2.YYYYMMDD, 3.YYMMDD, 4.MMDDYYYY, 5.MMDDYY";//ooooo
static con_str STRING_TIME_CONFIG_A = "Enter the index of preferred time format:";//ooooo
static con_str STRING_TIME_CONFIG_B = "0.AM_PM,1.TWENTY_FOUR";//ooooo
static con_str STRING_ORDER_CONFIG_A = "Enter the index of preferred order format:";//ooooo
static con_str STRING_ORDER_CONFIG_B = "0.HIGHT_TO_LOW,1.LOW_TO_HIGH";//ooooo
static con_str STRING_STATUS1 = "Task Examplar V0.0";
static con_str STRING_STATUS2 = "Code Done by Calvin,Chi Cheng,\r\n"
								"Deng Xuan and Shitong from NUS";
static con_str STRING_STATUS3 = "Events  Count: ";
static con_str STRING_STATUS4 = "Actions Count: ";
static con_str STRING_DUE_YES = "Click \"YES\" to mark an normal event done or an repeat event reminded.";
static con_str STRING_DUE_NO = "Click \"NO\" to mark the event missed.";

//con_str STRING_
const ByteInt ACTION_MARGIN = 8;
const ByteInt ACTION_EVENT_LENGTH = 25;
const ByteInt ACTION_TOTAL_LENGTH = 40;

const pos_int EVERYDAY_INDICATOR = 1;

const string TableCharSet[] = {
	"-", "|", "|", "|", "-", "-", "+",
	"=", "|", "*", "*", "*", "*", "|", "|", "=", "=",
};

enum class TableChar {
	SINGLE_HORIZONTAL = 0,
	SINGLE_VERTICAL = 1,
	SINGLE_VERTICAL_RIGHT = 2,
	SINGLE_VERTICAL_LEFT = 3,
	SINGLE_HORIZONTAL_DOWN = 4,
	SINGLE_HORIZONTAL_UP = 5,
	SINGLE_CROSS = 6,
	DOUBLE_HORIZONTAL = 7,
	DOUBLE_VERTICAL = 8,
	DOUBLE_TOP_LEFT = 9,
	DOUBLE_TOP_RIGHT = 10,
	DOUBLE_BOTTOM_LEFT = 11,
	DOUBLE_BOTTOM_RIGHT = 12,
	DOUBLE_VERTICAL_RIGHT = 13,
	DOUBLE_VERTICAL_LEFT = 14,
	DOUBLE_HORIZONTAL_DOWN = 15,
	DOUBLE_HORIZONTAL_UP = 16,
};

enum class TableParameter {
	TOTAL_WIDTH = 80,
	EVENT_WIDTH = 42,
	TIME_WIDTH = 35,
	REPEAT_WIDTH = 42,
	REMIND_WIDTH = 35,
	DONE_WIDTH = 24,
	REMINDED_WIDTH = 25,
	FLOATING_WIDTH = 27,
	TAGS_WIDTH = 78,
};
//<-End of constant list
//author A0087294R
class OutputDisplay{

private:
	string dueMsg;
    string upcomingText;
	string hintText;
    string inputText;
	string todayText;
	string missedText;
	string favouriteText;
	string floatingText;
	vector<Event> * _eventList;
	bool shouldUpcomingClear;
	bool _shutDown;
	bool _hasDue;
	OutputDisplay();
	OutputDisplay (const OutputDisplay&);
	void operator= (const OutputDisplay& );

//@author A0105495A
public:
	static OutputDisplay& get();
	PassedAction newAction;
	bool getShouldClearUpComing();
	bool availableDue() const ;
	void displayEvents(vector<pos_int> _IDList); 
	void displayToday (vector<pos_int> _IDList);
	void displayMissed (vector<pos_int> _IDList);
	void displayFavourite (vector<pos_int> _IDList);
	void displayFloating (vector<pos_int> _IDList);
	void displayError(IllegalInput errorType);
	string getTodayText();
	string getMissedText();
	string getFavouriteText();
	string getFloatingText();
	string getDueText();
	string getStatus();
	void showAdded(string detailAdded);
	void showdeleted(vector<pos_int> _IDDeleted,vector<pos_int> _IDIllegal);
	void showModifyStep2 (const vector<pos_int>& IDs);
	void showModifyStep3 (ModifyType newType);
	void showModifySuccess (const vector<pos_int>& modifiedIDs, const vector<pos_int>& notModifiedIDs);
	void showModifyStep2Error();///###########
	void showModifyStep1Error();///###########
    void showUndoneSuccess(pos_int stepNum);
    void showMarked(vector<pos_int> _IDMarked,vector<pos_int> _IDIllegal);	
	void showUpcomingString (const string & content);
	void showHint (const string& hint);
	void showSave ();
	void showConfig();  //ooooo
	void displayDateConfig();//ooooo
	void displayTimeConfig();//ooooo
	void displayOrderConfig();//ooooo
	void displayExitConfig();//ooooo
	void displayDateConfiged();//ooooo
	void displayIllegalConfig();//ooooo
	void displayTimeConfiged();//ooooo
	void displayOrderConfiged();//ooooo
	void displayHistory(con_str& history);
	void setAvailableDue (bool newBool);
	void showDue (Event&);
	void shutDown ();
	void clearConsole();
	bool shouldShutDown() const;
	string getUpcomingText();
	string getInputText();
	string getAcionListText();
	string getHintText();
	bool getIsModify();
};

typedef OutputDisplay * const ReadOutputDisplay;

static string toActionString (const PassedAction& oneAction) {
	string result = NULL_STRING;
	result += oneAction.getActionTime().toTimeString();
	result += SPACE_STRING;
	result += oneAction.getActionTime().toDateString();
	result += NEW_LINE;
	switch (oneAction.getOperationType()) {
	case OperationType::ADD:
		result += leftAlign(STRING_ADD, ACTION_MARGIN);
		break;
	case OperationType::DELETE_BY_NUMBER:
		result += leftAlign(STRING_DELETE, ACTION_MARGIN);
		break;
	case OperationType::MODIFY:
		result += leftAlign(STRING_MODIFY, ACTION_MARGIN);
		break;
	}
	result += chopString (oneAction.getEvent().getDetails(), ACTION_EVENT_LENGTH);
	result += NEW_LINE;
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL], ACTION_TOTAL_LENGTH);
	result += NEW_LINE;
	return result;
}

static string toStringOfRepeatRule (const REPEAT_RULE theRule) {
	string result = NULL_STRING;
	if (theRule.frequency == RepeatFrequency::NO_REPEAT ) {
		result += STRING_NEVER_REPEAT;
	}
	else {
		result += STRING_EVERY[0] + SPACE_STRING;
		if (theRule.startOfWeek != WeekDay::UNCLEAR) {
			result += capitaliseFirst(WEEKDAY_LIST[(pos_int)(theRule.startOfWeek)][0]);
			return result;
		}
		switch (theRule.frequency)
		{
		case RepeatFrequency::EVERY_N_DAY:
			if (theRule.period == EVERYDAY_INDICATOR) {
				result += STRING_DAY[0];
			}
			else {
				result += to_string((int)theRule.period);
				result += SPACE_STRING;
				result += STRING_DAY[1];
			}
			break;
		case RepeatFrequency::EVERY_MONTH:
			result += STRING_MONTH[0];
			break;
		default:
			failProgram (ERR_OutputDisplay::RepeatRule_ghost);
			break;
		}
	}
	return result;
}

static string outputBool (const bool theBool) {
	if (theBool) {
		return STRING_YES;
	}
	else {
		return STRING_NO;
	}
}

static string toDurationString (const Time& startTime, const Time& endTime, 
								bool duration = false, bool getStartTime = false) {
	string result = NULL_STRING;
	if (duration) {
		if (getStartTime) {
			result += STRING_START_WITH_COLON;
			result += startTime.toTimeString();
			result += SPACE_STRING;
			if (startTime.isCompletedDate()) {
				result += startTime.toDateString();
				result += SPACE_STRING;
				result += startTime.toDayOfWeekString();
			}
			else {
				result += STRING_NO_DATE;
			}
		}
		else {
			result += STRING_END_WITH_COLON;
			result += endTime.toTimeString();
			result += SPACE_STRING;
			if (endTime.isCompletedDate()) {
				result += endTime.toDateString();
				result += SPACE_STRING;
				result += endTime.toDayOfWeekString();
			}
			else {
				result += STRING_NO_DATE;
			}
		}
	}
	else {
		result += STRING_TIME_WITH_COLON;
		if (startTime.isEmpty() == false) {
			result += startTime.toTimeString();
			result += SPACE_STRING;
			if (startTime.isCompletedDate()) {
				result += startTime.toDateString();
				result += SPACE_STRING;
				result += startTime.toDayOfWeekString();
			}
			else {
				result += STRING_NO_DATE;
			}
		}
		else {
			result += STRING_NO_TIME;
		}
	}
	return result;
}

static string toRemindString (const Time& remindTime) {
	string result = NULL_STRING;
	if (remindTime.isEmpty() == false) {
		result += STRING_REMIND_WITH_COLON;
		result += remindTime.toTimeString();
			result += SPACE_STRING;
			if (remindTime.isCompletedDate()) {
				result += remindTime.toDateString();
				result += SPACE_STRING;
				result += remindTime.toDayOfWeekString();
			}
			else {
				result += STRING_NO_DATE;
			}
	}
	else {
		result = STRING_NO_REMIND;
	}
	return result;
}

static string toStringOfEvent (Event& theEvent, pos_int eventID, pos_int marginSize) {
	string result = NULL_STRING;
	
	result += leftAlign( to_string(eventID) + STRING_DOT,marginSize);
	//Generate the header of table
	result += TableCharSet[(pos_int)TableChar::DOUBLE_TOP_LEFT];
	result += getString (TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL], 
		(pos_int)TableParameter::EVENT_WIDTH);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL_DOWN];
	result += getString (TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL], 
		(pos_int)TableParameter::TIME_WIDTH);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_TOP_RIGHT];
	result += NEW_LINE;

	//Genrate the first row of the table
	//Details and time
	vector<string> details;
	pos_int firstRowHeight = 1;
	details = splitLines (theEvent.getDetails(), (pos_int)TableParameter::EVENT_WIDTH ,
		SEP_CHAR_LIST, SEP_CHAR_LIST_N);
	firstRowHeight = details.size();

	if (theEvent.isDuration() == true && firstRowHeight < 2) {
		firstRowHeight = 2;
		details.push_back (NULL_STRING);
	}

	for (pos_int i = 0; i < firstRowHeight; i++ ) {
		result += getString(SPACE_STRING, marginSize);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
		result += leftAlign (details[i], (pos_int) TableParameter::EVENT_WIDTH);
		result += TableCharSet[(pos_int)TableChar::SINGLE_VERTICAL];
		if (i == 0) {
			result += leftAlign(toDurationString (theEvent.getStartTime(),theEvent.getEndTime(), 
				theEvent.isDuration(), true), (pos_int)TableParameter::TIME_WIDTH);
		}
		else if (i == 1 && theEvent.isDuration() == true) {
			result += leftAlign(toDurationString (theEvent.getStartTime(), theEvent.getEndTime(),
				theEvent.isDuration(), false), (pos_int)TableParameter::TIME_WIDTH);
		}
		else {
			result += getString(SPACE_STRING, (pos_int)TableParameter::TIME_WIDTH);
		}
		result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
		result += NEW_LINE;
	}

	//Second row
	result += getString (SPACE_STRING, marginSize);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL_RIGHT];
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
		(pos_int)TableParameter::REPEAT_WIDTH);
	result += TableCharSet[(pos_int)TableChar::SINGLE_CROSS];
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
		(pos_int)TableParameter::REMIND_WIDTH);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL_LEFT];
	result += NEW_LINE;
	result += getString (SPACE_STRING, marginSize);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
	result += leftAlign (toStringOfRepeatRule(theEvent.getRepeatRule()), 
		(pos_int)TableParameter::REPEAT_WIDTH);
	result += TableCharSet[(pos_int)TableChar::SINGLE_VERTICAL];
	result += leftAlign (toRemindString (theEvent.getRemindTime()),
		(pos_int)TableParameter::REMIND_WIDTH);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
	result += NEW_LINE;
	
	//Third row
	result += getString (SPACE_STRING, marginSize);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL_RIGHT];
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
		(pos_int)TableParameter::DONE_WIDTH);
	result += TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL_DOWN];
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
		(pos_int)TableParameter::REPEAT_WIDTH-(pos_int)TableParameter::DONE_WIDTH-1);
	result += TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL_UP];
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
		(pos_int)((int)TableParameter::REMINDED_WIDTH -
		(int)TableParameter::REPEAT_WIDTH +
		(int)TableParameter::DONE_WIDTH));
	result += TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL_DOWN];
	result += getString (TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
		(pos_int)TableParameter::FLOATING_WIDTH);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL_LEFT];
	result += NEW_LINE;
	result += getString (SPACE_STRING, marginSize);
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
	if (theEvent.isDone() == true) {
		result += leftAlign(STRING_DONE_,(pos_int)TableParameter::DONE_WIDTH);
	}
	else {
		result += leftAlign(STRING_NOT_DONE, (pos_int)TableParameter::DONE_WIDTH);
	}
	result += TableCharSet[(pos_int)TableChar::SINGLE_VERTICAL];
	if (theEvent.isReminded() == true) {
		result += leftAlign (STRING_REMINDED_, (pos_int)TableParameter::REMINDED_WIDTH);
	}
	else {
		result += leftAlign (STRING_NOT_REMINDED, (pos_int)TableParameter::REMINDED_WIDTH);
	}
	result += TableCharSet[(pos_int)TableChar::SINGLE_VERTICAL];
	if (theEvent.isMissed() == true) {
		result += leftAlign (STRING_MISSED_, (pos_int)TableParameter::FLOATING_WIDTH);
	}
	else {
		result += leftAlign (STRING_NOT_MISSED, (pos_int)TableParameter::FLOATING_WIDTH);
	}
	result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
	result += NEW_LINE;
	
	
	if ((theEvent.getTagPtr()->size())!=0){
        vector<string> *_theTags = theEvent.getTagPtr();
		string tagsLine = NULL_STRING;
		tagsLine += STRING_TAGS;
        for (auto i:*_theTags){
            tagsLine += i;
            tagsLine += SPACE_STRING;
        }
	    
		vector<string> tagsLines;
		pos_int tagsRowHeight = 1;
		tagsLines = splitLines (tagsLine, (pos_int)TableParameter::TAGS_WIDTH ,
			SEP_CHAR_LIST, SEP_CHAR_LIST_N);
		firstRowHeight = tagsLines.size();
		result += getString(SPACE_STRING, marginSize);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL_RIGHT];
		result += getString(TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
			(pos_int)TableParameter::DONE_WIDTH);
		result += TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL_UP];
		result += getString(TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
			(pos_int)TableParameter::REMINDED_WIDTH);
		result += TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL_UP];
		result += getString(TableCharSet[(pos_int)TableChar::SINGLE_HORIZONTAL],
			(pos_int)TableParameter::FLOATING_WIDTH);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL_LEFT];
		result += NEW_LINE;
		for (pos_int i = 0; i < firstRowHeight; i++) {
			result += getString(SPACE_STRING, marginSize);
			result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
			result += leftAlign (tagsLines[i], (pos_int)TableParameter::TAGS_WIDTH);
			result += TableCharSet[(pos_int)TableChar::DOUBLE_VERTICAL];
			result += NEW_LINE;
		}
		result += getString(SPACE_STRING, marginSize);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_BOTTOM_LEFT];
		result += getString(TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL],
			(pos_int)TableParameter::TAGS_WIDTH);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_BOTTOM_RIGHT];
		result += NEW_LINE;
    }
	else {
		result += getString(SPACE_STRING, marginSize);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_BOTTOM_LEFT];
		result += getString(TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL],
			(pos_int)TableParameter::DONE_WIDTH);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL_UP];
		result += getString(TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL],
			(pos_int)TableParameter::REMINDED_WIDTH);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL_UP];
		result += getString(TableCharSet[(pos_int)TableChar::DOUBLE_HORIZONTAL],
			(pos_int)TableParameter::FLOATING_WIDTH);
		result += TableCharSet[(pos_int)TableChar::DOUBLE_BOTTOM_RIGHT];
		result += NEW_LINE;
	}
	return result;
}
